﻿
Imports std
Imports storoomc

Partial Public Class nodes_redundance2

    Private Delegate Function wmDelegate(ByVal key As String, ByVal buff As bytes) As Boolean

    Private Function _storageInterfaceWMImpl(ByVal si As storageInterface, ByVal key As String, _
                                             ByVal buff As bytes, ByVal ts As Int64, _
                                             ByVal wm As wmDelegate) As Boolean
        assert(Not si Is Nothing, "storageInterface is nothing.")
        assert(Not wm Is Nothing, "wmDelegate is nothing.")
        Return wm(datakey(key), buff) AndAlso si.modify(timestampkey(key), convertor.tobytes(ts))
    End Function

    Protected Overridable Function storageInterfaceModify(ByVal si As storageInterface, ByVal key As String, _
                                                          ByVal buff As bytes, ByVal ts As Int64) As Boolean
        assert(Not si Is Nothing)
        Return _storageInterfaceWMImpl(si, key, buff, ts, AddressOf si.modify)
    End Function

    Protected Overridable Function storageInterfaceWrite(ByVal si As storageInterface, ByVal key As String, _
                                                         ByVal buff As bytes, ByVal ts As Int64) As Boolean
        assert(Not si Is Nothing)
        Return _storageInterfaceWMImpl(si, key, buff, ts, AddressOf si.write)
    End Function

    Private Delegate Function wmDelegate2(ByVal si As storageInterface, ByVal key As String, _
                                          ByVal buff As bytes, ByVal ts As Int64) As Boolean

    Private Function _storageInterfaceWMImpl(ByVal si As storageInterface, ByVal key As String, _
                                             ByVal d As tsdata1, ByVal wm As wmDelegate2) As Boolean
        assert(Not d Is Nothing, "d is nothing.")
        assert(Not wm Is Nothing)
        Return wm(si, key, d.buff, d.ts)
    End Function

    Private Function storageInterfaceModify(ByVal si As storageInterface, ByVal key As String, _
                                            ByVal d As tsdata1) As Boolean
        Return _storageInterfaceWMImpl(si, key, d, AddressOf storageInterfaceModify)
    End Function

    Private Function storageInterfaceWrite(ByVal si As storageInterface, ByVal key As String, _
                                           ByVal d As tsdata1) As Boolean
        Return _storageInterfaceWMImpl(si, key, d, AddressOf storageInterfaceWrite)
    End Function

    Private Delegate Function wmDelegate3(ByVal si As storageInterface,
                                          ByVal key As String,
                                          ByVal ts As tsdata1) As Boolean

    Private Function storageInterfaceReadTimeStamp(ByVal si As storageInterface, ByVal key As String, _
                                                   ByRef ts As Int64) As Boolean
        assert(Not si Is Nothing, "storageInterface is nothing.")
        Dim tsbuff As bytes = Nothing
        If Not si.read(timestampkey(key), tsbuff) OrElse Not convertor.toint64(tsbuff, ts) Then
            Return False
        Else
            Return True
        End If
    End Function

    Protected Overridable Function storageInterfaceRead(ByVal si As storageInterface, ByVal key As String, _
                                                        ByRef buff As bytes, ByRef ts As Int64) As Boolean
        assert(Not si Is Nothing, "storageInterface is nothing.")
        If Not storageInterfaceReadTimeStamp(si, key, ts) Then
            'let ts be the oldest timestamp, so each other data can overwrite it
            ts = defaultTimeStamp
        End If
        If Not si.read(datakey(key), buff) Then
            ts = defaultTimeStamp
            Return False
        Else
            Return True
        End If
    End Function

    Private Function storageInterfaceRead(ByVal si As storageInterface, ByVal key As String,
                                          ByRef d As tsdata1) As Boolean
        If d Is Nothing Then
            d = New tsdata1()
        End If

        Return storageInterfaceRead(si, key, d.buff, d.ts)
    End Function

    Protected Overridable Function storageInterfaceSeek(ByVal si As storageInterface, ByVal key As String) As Boolean
        Return si.seek(datakey(key)) AndAlso si.seek(timestampkey(key))
    End Function

    Protected Overridable Function storageInterfaceList(ByVal si As storageInterface,
                                                        ByVal l As vector(Of String)) As Boolean
        assert(Not l Is Nothing)
        assert(l.empty())
        Dim v As vector(Of String) = Nothing
        If si.list(v) Then
            Dim i As Int64
            For i = 0 To v.size() - 1
                If isdatakey(v(i)) Then
                    l.push_back(originalkey(v(i)))
                End If
            Next

            Return True
        Else
            Return False
        End If
    End Function

    Protected Overridable Function storageInterfaceDelete(ByVal si As storageInterface,
                                                          ByVal key As String) As Boolean
        Return si.delete(datakey(key)) AndAlso si.delete(timestampkey(key))
    End Function

    Protected Overridable Function storageInterfaceSizeof(ByVal si As storageInterface,
                                                          ByVal key As String,
                                                          ByRef size As UInt64) As Boolean
        Return si.sizeof(datakey(key), size)
    End Function

    Protected Overridable Function storageInterfaceKeyCount(ByVal si As storageInterface,
                                                            ByRef count As UInt64) As Boolean
        If si.keycount(count) Then
            count >>= 1
            Return True
        Else
            Return False
        End If
    End Function
End Class
